/****************************************************************
* @file   : gen_data.cpp
* @author : NingJian (freegodly@gmail.com)
* @date   : 05/27/21 14:18:49
* @brief  : 生成light, dag数据
****************************************************************/

#include <iostream>
#include "eth_types.h"
#include "eth_func.hpp"
#include <memory>
#include "pcie_tools.hpp"
#include <chrono>
#include <fstream>


using namespace std;
using namespace eth;
using namespace eth::mcore;
using namespace std::chrono;
using timer = std::chrono::steady_clock;


int main(int argc, char *argv[])
{
    cout << "---------------说明-----------------" << endl;
    cout << "输入seed字符串值，生成数据文件" << endl;
    cout << "例如 ./gen_data 0x3646e1f9abad7750d559c03326ae5841c98e2fff3ee4ef7e1bc354b4499c946d" << endl;


    std::string sSeedHash = "0x3646e1f9abad7750d559c03326ae5841c98e2fff3ee4ef7e1bc354b4499c946d";

    if (argc == 2)
    {
        sSeedHash = std::string(argv[1]);
    }

    hash256 seed = hash256_from_string(sSeedHash);

    cout << "seed : " << hash256_to_string(seed) << endl;

    int epoch = find_epoch_number(seed);
    std::cout << "epoch : " << epoch << endl;

    auto start_time = timer::now();
    std::cout << "get_eth_context init start ..." << endl;
    std::shared_ptr<eth_context> context = get_eth_context(epoch, true);
    auto current_duration = double(duration_cast<milliseconds>(timer::now() - start_time).count());
    std::cout << "get_eth_context init times:" << current_duration / 1000.0 << "s" << endl;

    std::cout << "lightSize : " << context->light_cache_num_items * 64 / 1024.0 / 1024.0 << "MB" << endl;
    std::cout << "dagSize : " << (size_t)context->full_dataset_num_items * 128 / 1024.0 / 1024.0 / 1024.0 << "GB" << endl;

    std::cout << "full_dataset_num_items : " << context->full_dataset_num_items << endl;

    std::string file_name = std::string("light_epoch_") + std::to_string(epoch) + ".dat";
    ofstream lightFile(file_name, ios::ate|ios::out | ios::binary);
    for(size_t i =0; i < context->light_cache_num_items; ++i){
        lightFile.write((const char *)&(context->light_cache[i]), 64);
    }
    lightFile.close();

    std::cout << "save light file " << file_name << endl;
    

    file_name = std::string("dag_epoch_") + std::to_string(epoch) + ".dat";
    ofstream dagFile(file_name, ios::ate | ios::out | ios::binary);
    for(size_t i =0; i < context->full_dataset_num_items; ++i){
        dagFile.write((const char *)&(context->full_dataset[i]), 128);
    }
    dagFile.close();

    std::cout << "save dag file " << file_name << endl;

    return 0;
}